package com.sys.console.filter;

import java.util.HashSet;
import java.util.Set;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
@SuppressWarnings({ "rawtypes", "unchecked" })
/**
 * 请求参数的过滤
 */
public class XssHttpServletRequestWrapper extends HttpServletRequestWrapper {

	//请求中参数的白名单，不需要做转义
	private Set<String> whiteList;
	//请求中参数的忽略参数，不需要做转义
	private Set<String> ignore;
	
	public XssHttpServletRequestWrapper(HttpServletRequest request) {
		super(request);
		this.whiteList = new HashSet<String>();
		String[] whiteListStr = request.getParameterValues("whitelist");
		if(whiteListStr != null){
			for (int i = 0; i < whiteListStr.length; i++) {
				this.whiteList.add(whiteListStr[i]);
			}
		}
		this.ignore = new HashSet<String>();
		String[] ignoreStr = request.getParameterValues("ignore");
		if(ignoreStr != null){
			for (int i = 0; i < ignoreStr.length; i++) {
				this.ignore.add(ignoreStr[i]);
			}
		}
	}
	/**
	 * 
	  *  Function:
	  * 
	  *  @author wangchao  DateTime 2014-5-26 下午5:02:04
	  *  @param key
	  *  @param value
	 */
	public String xssEnocde(String key ,String value){
		value = xssEncode(value, whiteList.contains(key), ignore.contains(key));
		return value;
	}

	/**
	* 覆盖getHeader方法，将参数名和参数值都做xss过滤。<br/>
	* 如果需要获得原始的值，则通过super.getHeaders(name)来获取<br/>
	* getHeaderNames 也可能需要覆盖
	*/
	@Override
	public String getHeader(String name) {
		String value = super.getHeader(name);
		if (value != null) {
			value = xssEncode(value, false, true);
		}
		return value;
	}
	
	/**
	* 将容易引起xss漏洞的字符直接进行html转义
	*
	* @param s
	* @param isWhiteList 是否在白名单中，如果在，不做转义
	* @return
	*/
	private static String xssEncode(String s, boolean isWhiteList, boolean ignore) {
		if (s == null || s.isEmpty() || ignore) {
			return s;
		}
		if(isWhiteList){
			return HttpUtil.cleanUnsafeHTML(s);
		}else{
			return HttpUtil.xssEncode(s);
		}
	}

}
